package com.twu.biblioteca;

import com.twu.biblioteca.options.*;

import java.io.PrintStream;
import java.util.*;

public class BibliotecaApp {
    // Replace for acceptance testing
    public static int cycleFor = 10000000;
    public static PrintStream printStream = System.out;
    public static Scanner scanner = new Scanner(System.in);

    // AKA composition root
    public static void main(String[] args) {
        Map<String, User> users = new LinkedHashMap<String, User>();
        users.put("111-1111", new User("111-1111", "root".hashCode(), "John", "root@root.root", "1234567890"));
        UserRepository userRepository = new HardcodedUserRepository(users);
        UserInterface userInterface = new ConsoleUserInterface(scanner, printStream);
        ShowMembershipDetailsOption showMembershipDetailsOption = new ShowMembershipDetailsOption(userRepository, userInterface);

        List<Book> books = Arrays.asList(
                new Book("Culture Shock!", false),
                new Book("Moby Dick", false),
                new Book("Alice in Wonderland", false));
        BookRepository bookRepository = new HardcodedBookRepository(books);
        ViewBooksInCollectionOption viewBooksInCollectionOption = new ViewBooksInCollectionOption(userInterface, bookRepository);
        ReserveBookOption reserveBookOption = new ReserveBookOption(userInterface, bookRepository);

        List<Movie> movies = Arrays.asList(
                new Movie("Beethoven", "Brian Levant", 1992, 5),
                new Movie("Sholay", "Ramesh Sippy", 1975),
                new Movie("The Lord of the Rings: The Fellowship of the Ring", "Peter Jackson", 2001, 9),
                new Movie("Movie1", "Director12", 2000, 3),
                new Movie("Movie2", "Director11", 2012, 10),
                new Movie("Movie3", "Director10", 2000, 5),
                new Movie("Movie4", "Director9", 2010, 6),
                new Movie("Movie5", "Director8", 2003, 2),
                new Movie("Movie6", "Director7", 2005, 5),
                new Movie("Movie7", "Director6", 2007, 5),
                new Movie("Movie8", "Director5", 2009, 7),
                new Movie("Movie9", "Director4", 2002, 7),
                new Movie("Movie10", "Director3", 1998, 1),
                new Movie("Movie11", "Director2", 2005, 4),
                new Movie("Movie12", "Director1", 2005, 8)
        );
        MovieRepository movieRepository = new HardcodedMovieRepository(movies);
        ViewMoviesInCollectionOption viewMoviesInCollectionOption = new ViewMoviesInCollectionOption(userInterface, movieRepository);


        AuthenticationOptionDecorator protectedShowUsersOption = new AuthenticationOptionDecorator(showMembershipDetailsOption, userRepository);
        protectedShowUsersOption.setAlternativeDecoratedOption(new TalkToLibrarianOption(userInterface));

        List<Option> availableOptions = Arrays.asList(
                protectedShowUsersOption,
                viewBooksInCollectionOption,
                viewMoviesInCollectionOption,
                new AuthenticationOptionDecorator(reserveBookOption, userRepository),
                new LogInOption(userInterface, userRepository),
                new ExitOption());
        MenuOptions options = new MenuOptions(userInterface, availableOptions);
        Menu menu = new Menu(userInterface, options);

        launch(userInterface, menu);
    }

    private static void launch(UserInterface ui, Menu menu) {
        ui.showMessage("Welcome to Biblioteka!");

        while (cycleFor-- > 0) {
            menu.Execute();
        }
    }
}
